# Контекстуальные абстракции

### Background

Implicits в Scala 2 были главной отличительной особенностью дизайна. 
Это основной способ абстрагироваться от контекста.
Implicits представляют собой единую парадигму с большим разнообразием вариантов использования, среди которых:

- реализация type classes
- установление контекста
- внедрение зависимости (dependency injection)
- выражение возможностей
- вычисление новых типов и доказательство взаимосвязей между ними

С тех пор этому примеру последовали другие языки, например, 
[traits в Rust](https://doc.rust-lang.org/rust-by-example/trait.html) 
или [protocol extensions в Swift](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/). 
Предложения по дизайну также представлены для 
[Kotlin в качестве разрешения зависимостей во время компиляции](https://github.com/Kotlin/KEEP/blob/e863b25f8b3f2e9b9aaac361c6ee52be31453ee0/proposals/compile-time-dependency-resolution.md), 
для C# [в качестве Shapes и Extensions](https://github.com/dotnet/csharplang/discussions/164) 
или для [F# в качестве Traits](https://github.com/MattWindsor91/visualfsharp/blob/hackathon-vs/examples/fsconcepts.md).
Implicits также являются общей особенностью тех, кто доказывает теоремы, 
таких как [Coq](https://coq.inria.fr/refman/language/extensions/implicit-arguments.html)
или [Agda](https://agda.readthedocs.io/en/latest/language/implicit-arguments.html).

Несмотря на то, что в этих проектах используется разная терминология, 
все они являются вариантами основной идеи вывода терминов (_term inference_): 
учитывая тип, компилятор синтезирует "канонический" термин, который имеет этот тип.


### Редизайн

Scala 3 включает в себя переработку контекстных абстракций. 
Хотя эти концепции постепенно "открывались" в Scala 2, 
теперь они хорошо известны и понятны, и редизайн использует эти знания.

Дизайн Scala 3 фокусируется на **намерении**, а не на **механизме**. 
Вместо того, чтобы предлагать одну очень мощную функцию имплицитов, 
Scala 3 предлагает несколько функций, ориентированных на варианты использования:

- **Отвлечение контекстной информации**. 
[Предложения Using](abstractions/ca-using.md) 
позволяют программистам абстрагироваться от информации, которая доступна в контексте вызова и должна передаваться неявно. 
В качестве улучшения по сравнению со Scala 2 подразумевается, 
что предложения using могут быть указаны по типу, 
освобождая сигнатуры функций от имен переменных, на которые никогда не ссылаются явно.
- **Предоставление экземпляров Type-class**. 
[Given экземпляры](abstractions/ca-type-classes.md) позволяют программистам определять каноническое значение определенного типа. 
Это делает программирование с type-classes более простым без утечек деталей реализации.
- **Расширение классов**. 
В Scala 2 методы расширения должны были кодироваться с использованием неявных преобразований или неявных классов. 
Напротив, в Scala 3 [методы расширения](abstractions/ca-extension-methods.md) 
теперь встроены непосредственно в язык, что приводит к улучшению сообщений об ошибках и улучшению вывода типов.
- **Неявное преобразование одного типа в другой**.
Неявное преобразование было [переработано](abstractions/ca-implicit-conversions.md) с нуля 
как экземпляры type-class `Conversion`.
- **Контекстные абстракции более высокого порядка**. 
Совершенно новая функция [контекстных функций](type-system/types-dependent-function.md) 
делает контекстные абстракции объектами первого класса. 
Они являются важным инструментом для авторов библиотек и позволяют выражать лаконичный DSL.
- **Полезная обратная связь от компилятора**. 
Если компилятор не может разрешить неявный параметр, 
теперь он предлагает [предложения по импорту](https://www.scala-lang.org/blog/2020/05/05/scala-3-import-suggestions.html), 
которые могут решить проблему.


### Преимущества

Эти изменения в Scala 3 обеспечивают лучшее разделение вывода терминов от остального языка:

- существует единственный способ определить данные
- существует единственный способ ввести неявные параметры и аргументы
- существует отдельный способ [импорта givens](abstractions/ca-given-imports.md), 
который не позволяет им прятаться в море обычного импорта
- существует единственный способ определить [неявное преобразование](abstractions/ca-implicit-conversions.md), 
которое четко обозначено как таковое и не требует специального синтаксиса

К преимуществам этих изменений относятся:

- новый дизайн позволяет избежать взаимодействия функций и делает язык более согласованным
- implicits становятся более легкими для изучения и более сложными для злоупотреблений
- значительно улучшается ясность 95% программ Scala, использующих implicits

В этой главе в следующих разделах представлены многие из этих новых функций.


---

**Ссылки:**

- [Scala3 book, Contextual Abstractions](https://docs.scala-lang.org/scala3/book/ca-contextual-abstractions-intro.html)
- [Scala 3 Reference](https://docs.scala-lang.org/scala3/reference/contextual.html)
- [Scala 3 Contextual abstractions. Part I](https://medium.com/scala-3/scala-3-contextual-abstractions-part-i-3471676f2d23?source=rss----de7527e0301e---4)
- [Scala 3 Contextual abstractions. Part II](https://medium.com/scala-3/scala-3-contextual-abstractions-part-ii-35174c7f1baa?source=rss----de7527e0301e---4)
- [Scala 3 Contextual abstractions. Part III](https://medium.com/scala-3/scala-3-contextual-abstractions-part-iii-6b7be628a7de?source=rss----de7527e0301e---4)
